package com.xcgame.dlc;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.util.Log;

import com.jakewharton.disklrucache.DiskLruCache;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

/**
 * 磁盘本地缓存的工具类
 * <br/>
 * 需添加以下权限：
 * <br/>
 * ①android.permission.WRITE_EXTERNAL_STORAGE：往sdcard中写入数据的权限
 * <br/>
 * ②android.permission.MOUNT_UNMOUNT_FILESYSTEMS：在sdcard中创建/删除文件的权限
 *
 * @author 小灿
 */
public class DiskLruCacheUtil {
    private final String TAG = "DiskLruCacheUtil";

    /**
     * 最大缓存文件目录大小，这里为100MB
     */
    private final int CACHE_SIZE = 100 * 1024 * 1024;
    /**
     * 磁盘本地缓存的类
     */
    private DiskLruCache diskLruCache;

    private Context context;

    private String uniqueName;

    /**
     * 构造磁盘本地缓存的工具类对象
     *
     * @param context    上下文对象
     * @param uniqueName 文件路径，用于区别缓存文件类型
     * @return
     */
    public DiskLruCacheUtil(Context context, String uniqueName) {
        this.uniqueName = uniqueName;
        this.context = context;

        try {
            if (getDiskCacheDir().exists()) {
                getDiskCacheDir().mkdirs();
            }
            diskLruCache = DiskLruCache.open(getDiskCacheDir(), getAppVersion(), 1, CACHE_SIZE);
        } catch (IOException e) {
            e.printStackTrace();
            Log.d(TAG, "DiskLruCache初始化出现问题！！！");
        }
    }


    /**
     * 写入缓存文件（建议在子线程里执行此方法）
     *
     * @param fileName 写入缓存的文件名
     * @param bytes    写入缓存的文件的byte[]
     */
    public void write(String fileName, byte[] bytes) {
        String newFileName = MD5Util.md5(fileName);

        DiskLruCache.Editor editor = null;
        BufferedOutputStream bos = null;

        try {
            editor = diskLruCache.edit(newFileName);
            OutputStream os = editor.newOutputStream(0);
            bos = new BufferedOutputStream(os);
            bos.write(bytes);

            editor.commit();
            Log.v(TAG, "文件名：" + fileName + "；" + "写入成功！！！");

        } catch (IOException e) {
            e.printStackTrace();

            try {
                if (editor != null) {
                    editor.abort();
                }
            } catch (IOException e1) {
                e1.printStackTrace();

            }
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 读取已写入缓存的文件Text（建议在子线程里执行此方法）
     *
     * @param fileName 已写入缓存的文件名
     * @return 返回空为没有找到该缓存文本
     */
    public String readOfText(String fileName) {
        String newFileName = MD5Util.md5(fileName);

        StringBuffer sb = new StringBuffer();
        InputStreamReader isr = null;
        try {
            DiskLruCache.Snapshot snapShot = diskLruCache.get(newFileName);
            if (snapShot != null) {
                InputStream is = snapShot.getInputStream(0);
                isr = new InputStreamReader(is, "UTF-8");
                char[] chars = new char[1024];

                while (isr.read(chars) != -1) {
                    sb.append(chars);
                }
            }
            Log.d(TAG, "读取成功！！！");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (isr != null) {
                try {
                    isr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return sb.toString();
    }

    /**
     * 读取以缓存本地缓存文件为图片（建议在子线程里执行此方法）
     *
     * @param fileName
     * @return 返回空为没有找到该缓存图片
     */
    public Bitmap readOfBitmap(String fileName) {
        String newFileName = MD5Util.md5(fileName);

        Bitmap bitmap = null;
        BufferedInputStream bis = null;
        try {
            DiskLruCache.Snapshot snapShot = diskLruCache.get(newFileName);
            if (snapShot != null) {
                InputStream is = snapShot.getInputStream(0);
                bis = new BufferedInputStream(is);
                bitmap = BitmapFactory.decodeStream(bis);
            }
            Log.d(TAG, "读取成功！！！");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return bitmap;
    }


    /**
     * 缓存文件文件存放的位置
     *
     * @return
     */
    protected File getDiskCacheDir() {
        String cachePath;
        //如果sd卡存在并且没有被移除
        if (Environment.MEDIA_MOUNTED.equals(Environment
                .getExternalStorageState())
                || !Environment.isExternalStorageRemovable()) {
            cachePath = context.getExternalCacheDir().getPath();
        } else {
            cachePath = context.getCacheDir().getPath();
        }
        return new File(cachePath + File.separator + uniqueName);
    }

    /**
     * 获取App版本号
     */
    protected int getAppVersion() {
        try {
            PackageInfo info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }
}
